/*
 * Copyright (c) 2020-2020, org.smartboot. All rights reserved.
 * project name: smart-license
 * file name: License.java
 * Date: 2020-03-22
 * Author: sandao (zhengjunweimail@163.com)
 */

package org.smartboot.license.client;

import org.apache.commons.io.IOUtils;
import org.smartboot.license.client.common.Constant;
import org.smartboot.license.client.common.LicenseConfig;
import org.smartboot.license.client.common.LicenseException;

import javax.crypto.Cipher;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.List;

/**
 * @author 三刀
 * @version V1.0 , 2020/3/20
 */
public class License {
    private static final String KEY_ALGORITHM = "RSA";

    /**
     * 加载本地License
     *
     * @param file
     */
    public LicenseConfig loadLicense(File file) throws Exception {
        return loadLicense(new FileInputStream(file));
    }

    /**
     * 加载License
     *
     * @param inputStream
     */
    public LicenseConfig loadLicense(InputStream inputStream) throws Exception {
        List<String> lines = IOUtils.readLines(inputStream, "utf8");
        if (lines == null || lines.size() < Constant.LICENSE_LINES) {
            throw new LicenseException("Invalid License");
        }
        //公钥
        byte[] publicKey = Base64.getDecoder().decode(lines.get(0));
        //效期
        String date = new String(decryptByPublicKey(Base64.getDecoder().decode(lines.get(1)), publicKey));
        String[] dateSplit = date.split(Constant.DATE_SPLIT);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(Constant.DATE_FORMAT);
        Date registerDate = simpleDateFormat.parse(dateSplit[0]);
        Date expireDate = simpleDateFormat.parse(dateSplit[1]);
        if (registerDate.getTime() >= System.currentTimeMillis()) {
            throw new LicenseException("Invalid License");
        }
        if (expireDate.getTime() < System.currentTimeMillis()) {
            throw new LicenseException("License is expire");
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 2; i < lines.size(); i++) {
            stringBuilder.append(new String(decryptByPublicKey(Base64.getDecoder().decode(lines.get(i)), publicKey)));
        }
        LicenseConfig licenseData = new LicenseConfig();
        licenseData.setApplyDate(registerDate.toString());
        licenseData.setExpireDate(expireDate.toString());
        licenseData.setOriginal(stringBuilder.toString());
        return licenseData;
    }


    /**
     * 使用公钥进行解密
     *
     * @param data
     * @param publicKey
     * @return
     */
    private byte[] decryptByPublicKey(byte[] data, byte[] publicKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(publicKey);
            PublicKey pubKey = keyFactory.generatePublic(encodedKeySpec);
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, pubKey);
            return cipher.doFinal(data);
        } catch (Exception e) {
            throw new LicenseException("decrypt exception", e);
        }
    }
}
